extends CharacterBody2D

var size = 0
var speed = 0
var dir = Vector2(0, 0)
var inside = null
var sticks = []
var type = 0

@onready var bounce = preload("res://1/sound/Bubble Bounce.wav")
@onready var explode = preload("res://1/sound/Bubble Explode.wav")
@onready var grab = preload("res://1/sound/Bubble Get.wav")
@onready var stick = preload("res://1/sound/Bubble Stick.wav")
@onready var pops = [preload("res://1/sound/bubble-pop0.wav"), preload("res://1/sound/bubble-pop1.wav"), preload("res://1/sound/bubble-pop2.wav"), preload("res://1/sound/bubble-pop3.wav"), preload("res://1/sound/bubble-pop4.wav"), preload("res://1/sound/bubble-pop5.wav")]
@onready var absorbs = [preload("res://2/sounds/Bubble Absorb0.mp3"),preload("res://2/sounds/Bubble Absorb2.mp3"),preload("res://2/sounds/Bubble Absorb1.mp3")]
@onready var coll = preload("res://2/sounds/Bubble Collision.wav")

@onready var frames = [$tiny, $small, $medium, $big, $pop, $smallfull, $mediumfull, $bigfull, get_node("1full"), get_node("2full"), get_node("3full")]
@onready var char = get_node("/root/Main/Character")
@onready var main = get_node("/root/Main")

func _ready():
	$CollisionShape2D.shape = CircleShape2D.new()
	$CollisionShape2D.shape.radius = 24
	type = char.bubbletype
	if type == 3:
		$Area2D/CollisionShape2D.shape = CircleShape2D.new()
		$CollisionShape2D.shape.radius = 24

func grow():
	if $pop.visible == true:
		return
	size += 1
	for i in range(0, len(frames)):
		if i == size:
			frames[i].visible = true
		else:
			frames[i].visible = false
	if size == 4:
		dir = (global_position - char.global_position).normalized()
		if abs((-1*char.velocity.normalized()).angle_to(dir)) > 2*PI/3 and char.velocity.length() > 100:
			char.velocity = -250*(global_position - char.global_position).normalized()
		else:
			char.velocity += -250*(global_position - char.global_position).normalized()
		pop()
		return 1
	$CollisionShape2D.shape.radius += 24
	$CollisionShape2D.position.x += 24
	if type == 3:
		$Area2D/CollisionShape2D.shape.radius += 48
		$Area2D/CollisionShape2D.position = $CollisionShape2D.position
	$pop.scale += Vector2(1, 1)
	$pop.position.x += 24
	return 0
	
func launch():
	if type == 1 and size > 0:
		set_collision_mask_value(2, true)
	dir = (global_position - char.global_position).normalized()
	if abs((-1*char.velocity.normalized()).angle_to(dir)) > 2*PI/3 and char.velocity.length() > 100:
		if size == 0:
			speed = 20
			char.velocity += speed*dir*-4
			dir = dir.rotated(randf_range(-PI/4, PI/4)) 
		if size == 1:
			speed = 80
			char.velocity *= 0.6
		elif size == 2:
			speed = 200
			char.velocity *= 0.3
		elif size == 3:
			speed = 400
			char.velocity *= 0.1
		velocity = char.velocity + speed*dir
	else:
		var temp = char.velocity
		if size == 0:
			speed = 20
			char.velocity += speed*dir*-1
			dir = dir.rotated(randf_range(-PI/4, PI/4)) 
		if size == 1:
			speed = 80
			char.velocity += speed*dir*-0.15
		elif size == 2:
			speed = 200
			char.velocity += speed*dir*-0.15
		elif size == 3:
			speed = 400
			char.velocity += speed*dir*-0.25
		velocity = temp + speed*dir
	$Timer.start()
	
func pop():
	if type == 3 and size > 0:
		$pop.scale *= 2
		for i in $Area2D.get_overlapping_bodies():
			i.velocity = (i.global_position - global_position).normalized()*500
	for i in sticks:
		if i != null:
			i.sticks.erase(self)
	$AudioStreamPlayer2D.stream = pops[randi_range(0,5)]
	$AudioStreamPlayer2D.play()
	if inside != null:
		inside.global_position = global_position
		inside.get_node("CollisionShape2D").set_deferred("disabled", false)
		inside.get_node("AnimatedSprite2D").set_deferred("visible", true)
	velocity = Vector2(0, 0)
	$CollisionShape2D.disabled = true
	$pop.animation = "pop"
	for i in frames:
		if i == $pop:
			i.visible = true
		else:
			i.visible = false
	$pop.play()
	
func absorb(x):
	inside = x
	for i in frames:
		if i.visible == true:
			if "alien" in inside.name:
				inside.get_node("AudioStreamPlayer2D").stream = inside.sounds[3][inside.type-1]
				inside.get_node("AudioStreamPlayer2D").play()
				get_node(str(inside.type)+"full").visible = true
			else:
				$AudioStreamPlayer2D.stream = absorbs[randi_range(0, 2)]
				$AudioStreamPlayer2D.play()
				get_node(i.name+"full").visible = true
			i.visible = false
			break
	if sticks == []:
		velocity = inside.velocity*0.4
		global_position = inside.global_position
	else:
		inside.velocity = velocity
	inside.get_node("CollisionShape2D").set_deferred("disabled", true)
	inside.get_node("AnimatedSprite2D").set_deferred("visible", false)
	if type == 3:
		collect(false)
	
func collect(deep):
	if sticks != [] and deep == false:
		for i in sticks:
			i.collect(true)
	$AudioStreamPlayer2D.stream = grab
	$AudioStreamPlayer2D.play()
	if inside != null:
		if "alien" in inside.name and type != 3:
			char.powerup(inside.type)
			main.setscore(1000)
		elif "alien" in inside.name:
			main.setscore(1000)
		elif inside.size == 1:
			main.setscore(100)
		elif inside.size == 2:
			main.setscore(250)
		elif inside.size == 3:
			main.setscore(500)
		inside.queue_free()
	velocity = Vector2(0, 0)
	$CollisionShape2D.set_deferred("disabled", true)
	$pop.animation = "collect"
	for i in frames:
		if i == $pop:
			i.visible = true
		else:
			i.visible = false
	$pop.play()
	
func stuck(x):
	x.sticks = sticks
	x.sticks.erase(x)
	sticks.append(x)
	x.velocity = 0.5*(velocity + x.velocity)
	velocity = x.velocity
	for i in sticks:
		i.velocity = x.velocity
	
func _physics_process(delta: float) -> void:
	if move_and_slide() == true:
		collide(get_last_slide_collision().get_collider())
	if global_position.distance_to(char.global_position) > 10000:
		pop()
		
func collide(x):
	if x in sticks or x.size == 0:
		return
	if x.size > size and not (type == 1 and "bubble" in x.name) and not (type == 2 and size > 0):
		pop()
	elif x.name == "Character":
		$AudioStreamPlayer2D.stream = coll
		$AudioStreamPlayer2D.play()
		if type != 2:
			x.velocity = (x.global_position - global_position).normalized()*250
		else:
			x.velocity = (x.global_position - global_position).normalized()*500
	elif type == 1 and "bubble" in x.name:
		stuck(x)
	elif inside == null and "bubble" not in x.name and x.size <= size and velocity != Vector2(0, 0) and $smallfull.visible == false and $mediumfull.visible == false and $bigfull.visible == false:
		absorb(x)
	elif not (type == 1 and "bubble" in x.name):
		$AudioStreamPlayer2D.stream = coll
		$AudioStreamPlayer2D.play()
		if type != 2:
			x.velocity = (x.global_position - global_position).normalized()*250
		else:
			x.velocity = (x.global_position - global_position).normalized()*500


func _on_timer_timeout() -> void:
	set_collision_layer_value(1, true)

func _on_pop_animation_finished() -> void:
	queue_free()
